use crate::src::src::compare_int::int_compare;
use crate::src::src::rb_tree::{
    rb_tree_free, rb_tree_insert, rb_tree_lookup, rb_tree_lookup_node, rb_tree_new,
    rb_tree_node_child, rb_tree_node_key, rb_tree_node_value, rb_tree_num_entries, rb_tree_remove,
    rb_tree_root_node, rb_tree_to_array,
};
use crate::src::struct_and_type::{
    RBTree, RBTreeCompareFunc, RBTreeKey, RBTreeNode, RBTreeNodeSide, RBTreeValue, UnitTestFunction,
};
use crate::src::test::alloc_testing::{alloc_test_free, alloc_test_set_limit};
use crate::src::test::framework::run_tests;
use :: libc;
extern "C" {}
pub const RB_TREE_NODE_RIGHT: RBTreeNodeSide = 1;
pub const RB_TREE_NODE_LEFT: RBTreeNodeSide = 0;
#[no_mangle]
pub static mut test_array_test_rb_tree: [i32; 1000] = [0; 1000];
#[no_mangle]
pub extern "C" fn find_subtree_height_test_rb_tree(mut node: *mut RBTreeNode) -> i32 {
    let mut left_subtree: *mut RBTreeNode = 0 as *mut RBTreeNode;
    let mut right_subtree: *mut RBTreeNode = 0 as *mut RBTreeNode;
    let mut left_height: i32 = 0;
    let mut right_height: i32 = 0;
    if node.is_null() {
        return 0 as i32;
    }
    left_subtree = rb_tree_node_child(node, RB_TREE_NODE_LEFT);
    right_subtree = rb_tree_node_child(node, RB_TREE_NODE_RIGHT);
    left_height = find_subtree_height_test_rb_tree(left_subtree);
    right_height = find_subtree_height_test_rb_tree(right_subtree);
    if left_height > right_height {
        return left_height + 1 as i32;
    } else {
        return right_height + 1 as i32;
    };
}
#[no_mangle]
pub extern "C" fn validate_tree_test_rb_tree(mut _tree: *mut RBTree) {}
#[no_mangle]
pub extern "C" fn create_tree_test_rb_tree() -> *mut RBTree {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    let mut i: i32 = 0;
    tree = rb_tree_new(unsafe {
        ::core::mem::transmute::<
            Option<unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32>,
            RBTreeCompareFunc,
        >(Some(
            int_compare as unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32,
        ))
    });
    i = 0 as i32;
    while i < 1000 as i32 {
        (unsafe { test_array_test_rb_tree[i as usize] = i });
        rb_tree_insert(
            tree,
            (unsafe { &mut *test_array_test_rb_tree.as_mut_ptr().offset(i as isize) }) as *mut i32
                as RBTreeKey,
            (unsafe { &mut *test_array_test_rb_tree.as_mut_ptr().offset(i as isize) }) as *mut i32
                as RBTreeValue,
        );
        i += 1;
        i;
    }
    return tree;
}
#[no_mangle]
pub extern "C" fn test_rb_tree_new() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    tree = rb_tree_new(unsafe {
        ::core::mem::transmute::<
            Option<unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32>,
            RBTreeCompareFunc,
        >(Some(
            int_compare as unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32,
        ))
    });
    assert!(!tree.is_null());
    assert!((rb_tree_root_node(tree)).is_null());
    assert!(rb_tree_num_entries(tree) == 0 as i32);
    rb_tree_free(tree);
    alloc_test_set_limit(0 as i32);
    tree = rb_tree_new(unsafe {
        ::core::mem::transmute::<
            Option<unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32>,
            RBTreeCompareFunc,
        >(Some(
            int_compare as unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32,
        ))
    });
    assert!(tree.is_null());
}
#[no_mangle]
pub extern "C" fn test_rb_tree_insert_lookup() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    let mut node: *mut RBTreeNode = 0 as *mut RBTreeNode;
    let mut i: i32 = 0;
    let mut value: *mut i32 = 0 as *mut i32;
    tree = rb_tree_new(unsafe {
        ::core::mem::transmute::<
            Option<unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32>,
            RBTreeCompareFunc,
        >(Some(
            int_compare as unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32,
        ))
    });
    i = 0 as i32;
    while i < 1000 as i32 {
        (unsafe { test_array_test_rb_tree[i as usize] = i });
        rb_tree_insert(
            tree,
            (unsafe { &mut *test_array_test_rb_tree.as_mut_ptr().offset(i as isize) }) as *mut i32
                as RBTreeKey,
            (unsafe { &mut *test_array_test_rb_tree.as_mut_ptr().offset(i as isize) }) as *mut i32
                as RBTreeValue,
        );
        assert!(rb_tree_num_entries(tree) == i + 1 as i32);
        validate_tree_test_rb_tree(tree);
        i += 1;
        i;
    }
    assert!(!(rb_tree_root_node(tree)).is_null());
    i = 0 as i32;
    while i < 1000 as i32 {
        node = rb_tree_lookup_node(tree, &mut i as *mut i32 as RBTreeKey);
        assert!(!node.is_null());
        value = rb_tree_node_key(node) as *mut i32;
        assert!((unsafe { *value }) == i);
        value = rb_tree_node_value(node) as *mut i32;
        assert!((unsafe { *value }) == i);
        i += 1;
        i;
    }
    i = -(1 as i32);
    assert!((rb_tree_lookup_node(tree, &mut i as *mut i32 as RBTreeKey)).is_null());
    i = 1000 as i32 + 100 as i32;
    assert!((rb_tree_lookup_node(tree, &mut i as *mut i32 as RBTreeKey)).is_null());
    rb_tree_free(tree);
}
#[no_mangle]
pub extern "C" fn test_rb_tree_child() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    let mut root: *mut RBTreeNode = 0 as *mut RBTreeNode;
    let mut left: *mut RBTreeNode = 0 as *mut RBTreeNode;
    let mut right: *mut RBTreeNode = 0 as *mut RBTreeNode;
    let mut values: [i32; 3] = [1 as i32, 2 as i32, 3 as i32];
    let mut p: *mut i32 = 0 as *mut i32;
    let mut i: i32 = 0;
    tree = rb_tree_new(unsafe {
        ::core::mem::transmute::<
            Option<unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32>,
            RBTreeCompareFunc,
        >(Some(
            int_compare as unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32,
        ))
    });
    i = 0 as i32;
    while i < 3 as i32 {
        rb_tree_insert(
            tree,
            (unsafe { &mut *values.as_mut_ptr().offset(i as isize) }) as *mut i32 as RBTreeKey,
            (unsafe { &mut *values.as_mut_ptr().offset(i as isize) }) as *mut i32 as RBTreeValue,
        );
        i += 1;
        i;
    }
    root = rb_tree_root_node(tree);
    p = rb_tree_node_value(root) as *mut i32;
    assert!((unsafe { *p }) == 2 as i32);
    left = rb_tree_node_child(root, RB_TREE_NODE_LEFT);
    p = rb_tree_node_value(left) as *mut i32;
    assert!((unsafe { *p }) == 1 as i32);
    right = rb_tree_node_child(root, RB_TREE_NODE_RIGHT);
    p = rb_tree_node_value(right) as *mut i32;
    assert!((unsafe { *p }) == 3 as i32);
    assert!((rb_tree_node_child(root, 10000 as RBTreeNodeSide)).is_null());
    assert!((rb_tree_node_child(root, 2 as RBTreeNodeSide)).is_null());
    rb_tree_free(tree);
}
#[no_mangle]
pub extern "C" fn test_out_of_memory_test_rb_tree() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    let mut node: *mut RBTreeNode = 0 as *mut RBTreeNode;
    let mut i: i32 = 0;
    tree = create_tree_test_rb_tree();
    alloc_test_set_limit(0 as i32);
    i = 10000 as i32;
    while i < 20000 as i32 {
        node = rb_tree_insert(
            tree,
            &mut i as *mut i32 as RBTreeKey,
            &mut i as *mut i32 as RBTreeValue,
        );
        assert!(node.is_null());
        validate_tree_test_rb_tree(tree);
        i += 1;
        i;
    }
    rb_tree_free(tree);
}
#[no_mangle]
pub extern "C" fn test_rb_tree_free() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    tree = rb_tree_new(unsafe {
        ::core::mem::transmute::<
            Option<unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32>,
            RBTreeCompareFunc,
        >(Some(
            int_compare as unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32,
        ))
    });
    rb_tree_free(tree);
    tree = create_tree_test_rb_tree();
    rb_tree_free(tree);
}
#[no_mangle]
pub extern "C" fn test_rb_tree_lookup() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    let mut i: i32 = 0;
    let mut value: *mut i32 = 0 as *mut i32;
    tree = create_tree_test_rb_tree();
    i = 0 as i32;
    while i < 1000 as i32 {
        value = rb_tree_lookup(tree, &mut i as *mut i32 as RBTreeKey) as *mut i32;
        assert!(!value.is_null());
        assert!((unsafe { *value }) == i);
        i += 1;
        i;
    }
    i = -(1 as i32);
    assert!((rb_tree_lookup(tree, &mut i as *mut i32 as RBTreeKey)).is_null());
    i = 1000 as i32 + 1 as i32;
    assert!((rb_tree_lookup(tree, &mut i as *mut i32 as RBTreeKey)).is_null());
    i = 8724897 as i32;
    assert!((rb_tree_lookup(tree, &mut i as *mut i32 as RBTreeKey)).is_null());
    rb_tree_free(tree);
}
#[no_mangle]
pub extern "C" fn test_rb_tree_remove() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    let mut i: i32 = 0;
    let mut x: i32 = 0;
    let mut y: i32 = 0;
    let mut z: i32 = 0;
    let mut value: i32 = 0;
    let mut expected_entries: i32 = 0;
    tree = create_tree_test_rb_tree();
    i = 1000 as i32 + 100 as i32;
    assert!(rb_tree_remove(tree, &mut i as *mut i32 as RBTreeKey) == 0 as i32);
    i = -(1 as i32);
    assert!(rb_tree_remove(tree, &mut i as *mut i32 as RBTreeKey) == 0 as i32);
    expected_entries = 1000 as i32;
    x = 0 as i32;
    while x < 10 as i32 {
        y = 0 as i32;
        while y < 10 as i32 {
            z = 0 as i32;
            while z < 10 as i32 {
                value = z * 100 as i32 + (9 as i32 - y) * 10 as i32 + x;
                assert!(rb_tree_remove(tree, &mut value as *mut i32 as RBTreeKey) != 0 as i32);
                validate_tree_test_rb_tree(tree);
                expected_entries -= 1 as i32;
                assert!(rb_tree_num_entries(tree) == expected_entries);
                z += 1;
                z;
            }
            y += 1;
            y;
        }
        x += 1;
        x;
    }
    assert!((rb_tree_root_node(tree)).is_null());
    rb_tree_free(tree);
}
#[no_mangle]
pub extern "C" fn test_rb_tree_to_array() {
    let mut tree: *mut RBTree = 0 as *mut RBTree;
    let mut entries: [i32; 10] = [
        89 as i32, 23 as i32, 42 as i32, 4 as i32, 16 as i32, 15 as i32, 8 as i32, 99 as i32,
        50 as i32, 30 as i32,
    ];
    let mut sorted: [i32; 10] = [
        4 as i32, 8 as i32, 15 as i32, 16 as i32, 23 as i32, 30 as i32, 42 as i32, 50 as i32,
        89 as i32, 99 as i32,
    ];
    let mut num_entries: i32 = (::core::mem::size_of::<[i32; 10]>() as u64)
        .wrapping_div(::core::mem::size_of::<i32>() as u64) as i32;
    let mut i: i32 = 0;
    let mut array: *mut *mut i32 = 0 as *mut *mut i32;
    tree = rb_tree_new(unsafe {
        ::core::mem::transmute::<
            Option<unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32>,
            RBTreeCompareFunc,
        >(Some(
            int_compare as unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> i32,
        ))
    });
    i = 0 as i32;
    while i < num_entries {
        rb_tree_insert(
            tree,
            (unsafe { &mut *entries.as_mut_ptr().offset(i as isize) }) as *mut i32 as RBTreeKey,
            0 as *mut libc::c_void,
        );
        i += 1;
        i;
    }
    assert!(rb_tree_num_entries(tree) == num_entries);
    array = rb_tree_to_array(tree) as *mut *mut i32;
    i = 0 as i32;
    while i < num_entries {
        assert!((unsafe { **array.offset(i as isize) }) == sorted[i as usize]);
        i += 1;
        i;
    }
    alloc_test_free(array as *mut libc::c_void);
    alloc_test_set_limit(0 as i32);
    array = rb_tree_to_array(tree) as *mut *mut i32;
    assert!(array.is_null());
    validate_tree_test_rb_tree(tree);
    rb_tree_free(tree);
}
static mut tests_test_rb_tree: [UnitTestFunction; 7] = {
    [
        Some(test_rb_tree_new as unsafe extern "C" fn() -> ()),
        Some(test_rb_tree_free as unsafe extern "C" fn() -> ()),
        Some(test_rb_tree_child as unsafe extern "C" fn() -> ()),
        Some(test_rb_tree_insert_lookup as unsafe extern "C" fn() -> ()),
        Some(test_rb_tree_lookup as unsafe extern "C" fn() -> ()),
        Some(test_out_of_memory_test_rb_tree as unsafe extern "C" fn() -> ()),
        None,
    ]
};
fn main_0_test_rb_tree(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 {
    run_tests(unsafe { tests_test_rb_tree.as_mut_ptr() });
    return 0 as i32;
}
pub fn main_test_rb_tree() {
    let mut args: Vec<*mut i8> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    {
        ::std::process::exit(main_0_test_rb_tree(
            (args.len() - 1) as i32,
            args.as_mut_ptr() as *mut *mut i8,
        ) as i32)
    }
}
